package com.gws.ievent.common.utils;

import com.alibaba.fastjson.JSON;
import okhttp3.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;


/**
 * @author song
 * @date 2022/10/22 18:20
 */
public class OkHttpUtil {
    private static final OkHttpClient CLIENT = new OkHttpClient();


    /**
     * post json格式请求
     *
     * @param url
     * @param headers
     * @param body
     * @return
     * @throws IOException
     */
    public static String postJson(String url, Map<String, String> headers, Object body) throws IOException {
        return new OkHttpUtil().post(url, headers, body, null, true);
    }

    /**
     * get 请求
     *
     * @param url
     * @param headers
     * @param params
     * @return
     * @throws IOException
     */
    public static String get(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
        return new OkHttpUtil().gets(url, headers, params);
    }


    /**
     * Get请求
     *
     * @param url
     * @param headers
     * @param params
     * @return
     * @throws IOException
     */
    public String gets(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
        Request request = new Request.Builder()
                .url(this.params(url, params))
                .headers(this.headers(headers))
                .get()
                .build();

        return this.exec(request);
    }


    /**
     * post请求
     *
     * @param url
     * @param headers
     * @param body
     * @param params
     * @return
     * @throws IOException
     */
    public String post(String url, Map<String, String> headers, Object body, Map<String, String> params, boolean isJsonPost) throws IOException {
        Request request = new Request.Builder()
                .url(this.params(url, params))
                .headers(this.headers(headers))
                .post(isJsonPost ? this.jsonBody(body) : this.formBody(body))
                .build();

        return this.exec(request);
    }


    /**
     * 添加请求头
     *
     * @param headers
     * @param headers
     */
    private Headers headers(Map<String, String> headers) {
        Headers.Builder builder = new Headers.Builder();
        if ((headers != null) && (headers.size() > 0)) {
            for (String s : headers.keySet()) {
                builder.add(s, headers.get(s));
            }
        }

        return builder.build();
    }


    /**
     * 添加 requestParam 请求参数
     *
     * @param url
     * @param params
     * @return
     */
    private String params(String url, Map<String, String> params) {
        if ((url == null) || (url.length() == 0) || (params == null) || (params.size() == 0)) {
            return url;
        }

        StringBuilder urlBuilder = new StringBuilder();
        try {
            for (String key : params.keySet()) {
                if (key == null) {
                    continue;
                }

                String value = params.get(key);
                if (value == null) {
                    continue;
                }

                urlBuilder.append(URLEncoder.encode(key, "utf-8")).
                        append("=").
                        append(URLEncoder.encode(value, "utf-8")).
                        append("&");
            }
        } catch (UnsupportedEncodingException e) {
            return url;
        }

        String paramsStr = urlBuilder.deleteCharAt(urlBuilder.length() - 1).toString();
        return url + "?" + paramsStr;
    }


    /**
     * json数据格式
     * application/json
     *
     * @param body
     * @return
     */
    private RequestBody jsonBody(Object body) {
        return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSON.toJSONString(body));
    }


    /**
     * 表单数据格式
     *
     * @param body
     * @return
     */
    private RequestBody formBody(Map<String, String> body) {
        FormBody.Builder builder = new FormBody.Builder();
        if ((body != null) && (body.size() > 0)) {
            for (String key : body.keySet()) {
                builder.add(key, body.get(key));
            }
        }

        return builder.build();
    }


    /**
     * 表单数据格式
     *
     * @param body
     * @return
     */
    private RequestBody formBody(Object body) {
        return this.formBody(StringUtil.beanToStringMap(body));
    }


    /**
     * 执行请求并获取结果
     *
     * @param request
     * @return
     * @throws IOException
     */
    private String exec(Request request) throws IOException {
        try (Response response = CLIENT.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }

            return response.body().string();
        }
    }

}
